/**
 * 
 */
package com.junge.utils;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.junge.jedis.JedisTool;
import com.junge.jedis.UserInfo;
import com.junge.jedis.UserInfoTool;

/**
 * 类描述 :
 * @author xiaojun.yin
 * @version 1.0
 * 2019年1月27日 下午3:45:48
 */
public class NetTools {
	
	private static String sendHost = "https://pre.api.clife.cn";
	private static String localTimestamp = "0";
	private static String myAppId = "31038";
	private static String myAppSecret = "f7d2b4a96e644d24a4c1e8fc6add6484";
	
	private static String loginSendUrl = "/v1/account/login";
	private static String userIdSendUrl = "/v1/user/get";
	private static String userDeviceIdListUrl = "/v1/device/getBind";
	private static String meDeviceIdListUrl = "/v4/app/agriculture/device/myDeviceList";
	
	static AtomicInteger enir = new AtomicInteger(0);
	
	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年1月27日 下午3:51:33
	 * @param account
	 * @param pwd
	 * @return
	 * @throws Exception 
	 */
	public static Integer getAccountIdByAccount(String account, String pwd) throws Exception {
		initEnir();
		String currentToken = getAccessToken(account,pwd);
		String userId = getUserId(currentToken);
		if(!StringUtil.isEmpty(userId)){
			return Integer.valueOf(userId);
		}
		return null;
	}
	
	private static String getUserId(String accessToken) throws Exception {
		String secretUrl = sendHost+userIdSendUrl+"?appId=31038&timestamp="+localTimestamp
				+"&accessToken="+ accessToken;
		JsonNode jsonNode = thisSendGet(secretUrl);
		if (jsonNode != null) {
			JsonNode data = jsonNode.path("data");
			String userId = data.path("userId").asText();
			userId = AESCryptoSecurity.decrypt(userId, myAppSecret);
			System.out.println("userId = "+userId);
			return userId;
		} 
		return null;
	}
	/**
	 * 登录
	 * @param pwd 
	 * @param account 
	 * @throws Exception 
	 * **/
	private static String getAccessToken(String account, String pwd) throws Exception {
		String sign = getLoginSign(account,pwd);
		String loginUrl = createLoginUrl(account,pwd,sign);
		JsonNode jsonNode = thisSendPost(loginUrl);
		if (jsonNode.path("code").asInt() == 0) {
			JsonNode data = jsonNode.path("data");
			System.out.println("accessToken = "+data.path("accessToken").asText());
			System.out.println("accessTokenExpires = "+data.path("accessTokenExpires").asText());
			System.out.println("refreshToken = "+data.path("refreshToken").asText());
			System.out.println("refreshTokenExpires = "+data.path("refreshTokenExpires").asText());
			changeUserId(account,data.path("accessToken").asText());
			return  data.path("accessToken").asText();
		} else {
			System.out.println("请求失败结果：   " + jsonNode);
			return jsonNode.toString();
		}
	}
	
	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年2月25日 下午5:56:30
	 * @param account
	 * @param asText
	 * @throws Exception 
	 */
	private static void changeUserId(String account, String accessToken) throws Exception {
		String userId = getUserId(accessToken);
		UserInfoTool.changUserIdInfo(account,userId);
	}

	public static String getLoginSign(String account, String pwd) {
		StringBuilder signUrl = new StringBuilder();
		signUrl.append("POST" + sendHost);
		signUrl.append(loginSendUrl+"account=" + account);
		signUrl.append("&appId=" + myAppId);
		signUrl.append("&password=" + getPassword(pwd));
		signUrl.append("&timestamp=" + localTimestamp + "&");
		signUrl.append(myAppSecret);
		return DigestUtils.md5Hex(signUrl.toString());
	}
	
	private static String createLoginUrl(String account, String pwd,String sign) {
		StringBuilder loginUrl = new StringBuilder();
		loginUrl.append(sendHost);
		loginUrl.append(loginSendUrl+"?appId=" + myAppId);
		loginUrl.append("&timestamp=" + localTimestamp);
		loginUrl.append("&account=" + account);
		loginUrl.append("&password=" + getPassword(pwd));
		loginUrl.append("&sign=" + sign);
//		loginUrl.append("&random=" + System.currentTimeMillis()%100000);
		return loginUrl.toString();
	}
	
	private static void initEnir() {
		if(0 == enir.get()){
			sendHost = "https://dp.clife.net";
		}else if(1 == enir.get()){
			sendHost = "https://pre.api.clife.cn";
		}else if(2 == enir.get()){
			sendHost = "10.8.9.15://8080";
		}
		myAppId = "31038";
		myAppSecret = "c9596887fdd844499e0f53a6af39044f";
		localTimestamp = System.currentTimeMillis() + "";
		
	}
	public static String getPassword(String pwd) {
		if (pwd.length() == 24) {
			return DigestUtils.md5Hex(pwd + myAppSecret);
		}
		return DigestUtils.md5Hex(Base64.encodeBase64String(DigestUtils.md5(pwd)) + myAppSecret);
	}
	
	/**发送post  请求
	 * @param param */
	private static JsonNode thisSendPost(String sendUrl, Map<String,String> param) {
		long start = System.currentTimeMillis();
		System.out.println("~~~~~~~~~~~~~~开始~~~~~~~~~~~~~"+start );
		System.out.println("开始请求了：" + sendUrl+"?"+param);
		String resp = HttpClientUtil.sendPostSSLRequest(sendUrl,param,null);
//		String resp = HttpClientUtil.sendPostRequest(sendUrl, param, "utf-8");
		System.out.println("返回结果是：" + resp);
		long end = System.currentTimeMillis();
		System.out.println("~~~~~~~~结束~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" +(end-start));
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = null;
		try {
			jsonNode = mapper.readTree(resp);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonNode;
	}
	/**发送post  请求*/
	private static JsonNode thisSendPost(String sendUrl) {
		long start = System.currentTimeMillis();
		System.out.println("~~~~~~~~~~~~~~开始~~~~~~~~~~~~~"+start );
		System.out.println("开始请求了：" + sendUrl);
		String resp = HttpClientUtil.sendPostSSLRequest(sendUrl, null, null);
		System.out.println("返回结果是：" + resp);
		long end = System.currentTimeMillis();
		System.out.println("~~~~~~~~结束~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" +(end-start));
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = null;
		try {
			jsonNode = mapper.readTree(resp);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonNode;
	}
	
	/**发送get  请求*/
	private static JsonNode thisSendGet(String sendUrl) {
		System.out.println("~~~~~~~~~~~~~~开始~~~~~~~~~~~~~" );
		System.out.println("开始请求了：" + sendUrl);
		String resp = HttpClientUtil.sendGetSSLRequest(sendUrl);
		System.out.println("返回结果是：" + resp);
		System.out.println("~~~~~~~~结束~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = null;
		try {
			jsonNode = mapper.readTree(resp);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (jsonNode.path("code").asInt() == 0) {
			return jsonNode;
		} else {
			System.out.println("请求失败结果：   " + jsonNode);
			return null;
		}
	}

	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年1月27日 下午4:48:13
	 * @param account
	 * @param pwd
	 * @return
	 * @throws Exception 
	 */
	public static String login(String account, String pwd) throws Exception {
		initEnir();
		String currentToken = getAccessToken(account,pwd);
		return "登录结果："+currentToken;
	}

	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年1月27日 下午5:46:32
	 * @param account
	 * @param pwd
	 * @return
	 * @throws Exception 
	 */
	public static String getMyDeviceList(String account, String pwd) throws Exception {
		initEnir();
		UserInfo userInfo = JedisTool.getUserTokenInfo(account, pwd);
		if (userInfo.getAcountId() == null) {
			return "找不到用户："+userInfo.toString();
		}
		Map<String,Object> result = new HashMap<>();
		try {
			String sendUrl = sendHost + userDeviceIdListUrl + "?version=1.2&accessToken="+userInfo.getAccessToken()+"&appId="+myAppId+"&timestamp="+System.currentTimeMillis();
			JsonNode jn = thisSendGet(sendUrl);
			Map<String, Object> resultMap = JacksonUtil.readObjectValue(jn.toString(), Map.class);
			if("0".equals(String.valueOf(resultMap.get("code")))){
				List<Map<String,Object>> deviceMapList = new ArrayList<>();
				if(!"[]".equals(String.valueOf(resultMap.get("data")))){
					List<Map> dataList = JacksonUtil.readListValue(JacksonUtil.ObjectToJsonString(resultMap.get("data")), Map.class);
					if(dataList != null && dataList.size()>0){
						for (Map map : dataList) {
							Map<String,Object> deviceMap = new HashMap<>();
							deviceMap.put("productId", map.get("productId"));
							deviceMap.put("deviceId", map.get("deviceId"));
							deviceMap.put("deviceId_decrypt", AESCryptoSecurity.decrypt(String.valueOf(map.get("deviceId")), myAppSecret));
							deviceMap.put("onlineStatus", map.get("onlineStatus"));
							deviceMap.put("deviceName", map.get("deviceName"));
							deviceMapList.add(deviceMap);
						}
					}
				}
				result.put("center", deviceMapList); 
			}else{
				result.put("centerMsg", resultMap.get("data")); 
			}
			sendUrl = sendHost + meDeviceIdListUrl + "?version=2.1.0&accessToken="+userInfo.getAccessToken()+"&appId="+myAppId+"&timestamp="+System.currentTimeMillis();	
			jn = thisSendGet(sendUrl);
			resultMap = JacksonUtil.readObjectValue(jn.toString(), Map.class);
			if("0".equals(String.valueOf(resultMap.get("code")))){
				List<Map<String,Object>> deviceMapList = new ArrayList<>();
				Map<String,Object> dataMap = (Map<String, Object>) resultMap.get("data");
				putDeviceInList(dataMap,deviceMapList,"concurrentDevice");
				putDeviceInList(dataMap,deviceMapList,"farVideoDevice");
				putDeviceInList(dataMap,deviceMapList,"farControlDevice");
				result.put("AINong", deviceMapList); 
			}else{
				result.put("AINongMsg", resultMap.get("data")); 
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return showResultDeviceInfos(result);
	}
	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年1月27日 下午6:48:05
	 * @param dataMap
	 * @param deviceMapList 
	 * @param mapKey 
	 */
	private static void putDeviceInList(Map<String, Object> dataMap, List<Map<String, Object>> deviceMapList, String mapKey) {
		if(!"[]".equals(String.valueOf(dataMap.get(mapKey)))){
			List<Map> dataList = JacksonUtil.readListValue(JacksonUtil.ObjectToJsonString(dataMap.get(mapKey)), Map.class);
			if(dataList != null && dataList.size()>0){
				for (Map map : dataList) {
					Map<String,Object> deviceMap = new HashMap<>();
					deviceMap.put("deviceModel", map.get("deviceModel"));
					deviceMap.put("deviceId", map.get("deviceId"));
					try {
						deviceMap.put("deviceId_decrypt", AESCryptoSecurity.decrypt(String.valueOf(map.get("deviceId")), myAppSecret));
					} catch (Exception e) {
						deviceMap.put("deviceId_decrypt", "ID解析错误");
					} 
					deviceMap.put("deviceImei", map.get("deviceImei"));
					deviceMap.put("deviceMac", map.get("deviceMac"));
					deviceMap.put("deviceName", map.get("deviceName"));
					deviceMap.put("blockId", map.get("blockId"));
					deviceMap.put("blockName", map.get("blockName"));
					deviceMap.put("agricultureProductTypeId", map.get("agricultureProductTypeId"));
					deviceMap.put("agricultureProductName", map.get("agricultureProductName"));
					String deviceBean = StringUtil.showStringLength(String.valueOf(map.get("deviceBean")), 9);
					deviceMap.put("deviceBean", deviceBean);
					deviceMapList.add(deviceMap);
				}
			}
		}
		
	}

	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年1月27日 下午6:24:28
	 * @param result
	 * @return
	 */
	private static String showResultDeviceInfos(Map<String, Object> resultMap) {
		String result = "";
		if(resultMap.containsKey("center")){
			List<Map<String,Object>> tempMap = (List<Map<String, Object>>) resultMap.get("center");
			result += "公共模块获取到的设备列表："+showMapMsg(tempMap);
		}else{
			result += "公共模块获取到的设备列表："+resultMap.get("centerMsg");
		}
		if(resultMap.containsKey("AINong")){
			List<Map<String,Object>> tempMap = (List<Map<String, Object>>) resultMap.get("AINong");
			result += "\n........\nAI农获取到的设备列表："+showMapMsg(tempMap);
		}else{
			result += "\n........\nAI农获取到的设备列表："+resultMap.get("AINongMsg");
		}
		return result;
	}

	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年1月27日 下午6:28:16
	 * @param tempMap
	 * @return
	 */
	private static String showMapMsg(List<Map<String, Object>> tempMap) {
		StringBuilder sb = new StringBuilder("数量：");
		sb.append(tempMap.size());
		sb.append("\n[");
		for (Map<String, Object> map : tempMap) {
			sb.append("{");
			for(String key:map.keySet()){
				sb.append("    ").append(key+":").append(map.get(key)).append("\n");
			}
			sb.append("}");
		}
		sb.append("]");
		return sb.toString();
	}

	public static void main(String[] args) {
		try {
			System.out.println(AESCryptoSecurity.decrypt("E1CA60E1A71890FEBAC76D874736DB55", "c9596887fdd844499e0f53a6af39044f"));
			System.out.println(getMyDeviceList("15238908120", "qwe123456"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年2月25日 下午5:21:44
	 * @param i
	 */
	public static void changeEnir(int index) {
		enir.set(index);
		
	}

	/**
	 * 方法功能描述 :
	 * @author xiaojun.yin
	 * 2019年2月25日 下午6:12:22
	 * @return
	 */
	public static String getEnirName() {
		if(0 == enir.get()){
			return  "_test";
		}else if(1 == enir.get()){
			return  "_pre";
		}else if(2 == enir.get()){
			return   "";
		}
		return null;
	}
}
